package com.xiaotao.learn.thread.concurrent.cas.simple;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CASTest {
    private final static int THREAD_CNT = 8;
    private final static int INCREASE_CNT = 100000;
    public static void main(String[] args) {
        NumberHandler[] testGroup = new NumberHandler[]{
                new UnsafeHandler(),
                new SyncHandler(),
                new CASHandler()
        };

        for (NumberHandler handler : testGroup) {
            doTest(handler, THREAD_CNT, INCREASE_CNT);
        }

        for (int i = 1; i <= THREAD_CNT; i++) {
            System.out.println("线程数：" + i);
            for (NumberHandler handler : testGroup) {
                long except = THREAD_CNT * INCREASE_CNT;
                long l = doTest(handler, i, INCREASE_CNT);
                System.out.println(handler.getClass().getSimpleName() + " 预期:" + except + " 实际:" + handler.getValue() + " 耗时：" + l);
                handler.reset();
            }
        }
    }

    public static long doTest(NumberHandler handler, int threadCount, int increaseCount) {
        long start = System.currentTimeMillis();
        CyclicBarrier barrier = new CyclicBarrier(threadCount + 1);
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < increaseCount; j++) {
                        handler.increase();
                    }
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        try {
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
        return System.currentTimeMillis() - start;
    }
}
